#ifndef __CLOG_H__
#define __CLOG_H__
#include "ringBuffer.h"
#include <string>

using namespace std;

typedef struct LogData
{
    string date;
    string data;
    string level;
} LogData;

enum LEVEL
{
    debug = 0,
    info,
    error,
    MAX_INDEX
};

class Clog
{
public:
    Clog();
    ~Clog();
    void write_log_asyn(string data, int level = 0);
    void write_log_sync(string data, int level = 0);
    static Clog *getInstance()
    {
        static Clog log_handler;
        return &log_handler;
    }

    void start_thread();
    string filename;
    string path;
    int level; // 日志等级
    bool is_sync;
private:
    FILE *fp;
    int running;
    RingBuffer<LogData> queue;
    string today; // 当天日期
    void recv_thread();
    int do_write_log();
};

#define INIT_LOG(p, file, lv, boolvar)                 \
{                                         \
    Clog::getInstance()->level = lv;      \
    Clog::getInstance()->filename = file; \
    Clog::getInstance()->path = p;        \
    Clog::getInstance()->start_thread();  \
    Clog::getInstance()->is_sync = boolvar; \
    }

#define LOG(format, ...)                                                                    \
{                                                                                         \
    char __buf[1024] = "";                                                                  \
    snprintf(__buf, sizeof(__buf) - 1, "[%s:%d]:" format,  __FILE__, __LINE__, ##__VA_ARGS__); \
    if(Clog::getInstance()->is_sync )\
        Clog::getInstance()->write_log_sync(string(__buf));                                          \
    else\
         Clog::getInstance()->write_log_asyn(string(__buf));\
    }

#define LOG_LEVEL(level, format, ...)                                                       \
{                                                                                         \
    char __buf[1024] = "";                                                                  \
    snprintf(__buf, sizeof(__buf) - 1, "[%s:%d]:" format, __FILE__, __LINE__, ##__VA_ARGS__); \
    Clog::getInstance()->write_log_asyn(string(__buf), level);                                   \
    }

#endif
